openapi: 3.0.3
info:
  title: Device Geofencing Subscriptions
  description: >
    API to create, retrieve and delete event subscriptions to realize geofencing
    for a user device.


    # Introduction


    With this API, API consumers can create subscriptions for their devices to
    receive notifications when a device enters or exits a specified area.


    The area provided in the request is described by a circle determined by
    coordinates (latitude and longitude) and an accuracy defined by the radius.


    Upon successfully creating a subscription, the API will provide an Event
    Subscription ID, and it will indicate the subscription's expiration date.


    If the geofencing-state of a device changes, the event subscriber will be
    notified back to the provided Notification-Url given by the
    subscription-request.


    Device geofencing API could be useful in scenarios such as:


    - Tracking devices for Presetting of Home-Settings

    - Tracking of logistics


    # Relevant terms and definitions


    * **Device**: A device refers to any physical entity that can connect to a
    network and participate in network communication.


    * **Area**: It specifies the geographical surface which a device is planned
    to enter or exit.


    # API Functionality


    The API exposes following capabilities:


    ## Device Geofencing subscription

    These endpoints allow to manage event subscription on geofencing device
    location event.


    The CAMARA subscription model is detailed in the CAMARA API design guideline
    document and follows CloudEvents specification.


    It is mandatory in the subscription to provide the event `type` for which
    the client would like to subscribe.


    Following event ``types`` are managed for this API:
      - ``org.camaraproject.geofencing-subscriptions.v0.area-entered``  - Event triggered when the device enters the given area

      - ``org.camaraproject.geofencing-subscriptions.v0.area-left``     - Event triggered when the device leaves the given area

    Note: Additionally to these list,
    ``org.camaraproject.geofencing-subscriptions.v0.subscription-ends``
    notification `type` is sent when the subscription ends.

    This notification does not require dedicated subscription.


    It is used when:
      - the subscription expire time (optionally set by the requester) has been reached
      - the maximum number of subscription events (optionally set by the requester) has been reached
      - the subscription was deleted by the requester
      - the Access Token `sinkCredential` (optionally set by the requester) expiration time has been reached
      - the API server has to stop sending notification prematurely
      - the specified geofence-`area` cannot be covered or is too small to be managed

    ### Notification callback


    This endpoint describes the event notification received on subscription
    listener side when the event occurred.

    As for subscription, detailed description of the event notification is
    provided in the CAMARA API design guideline document.


    _**WARNING**: This callback endpoint must be exposed on the consumer side as
    `POST /{$request.body#/sink}`.
      Developers may provide a callback URL on which notifications regarding geofencing can be received from the service provider.
      If an event occurs the application will send events to the provided webhook - 'sink'._

    # Authorization and authentication


    The "Camara Security and Interoperability Profile" provides details on how a
    client requests an access token. Please refer to Identify and Consent
    Management (https://github.com/camaraproject/IdentityAndConsentManagement/)
    for the released version of the Profile.


    Which specific authorization flows are to be used will be determined during
    onboarding process, happening between the API Client and the API Provider,
    taking into account the declared purpose for accessing the API, while also
    being subject to the prevailing legal framework dictated by local
    legislation.


    It is important to remark that in cases where personal user data is
    processed by the API, and users can exercise their rights through mechanisms
    such as opt-in and/or opt-out, the use of 3-legged access tokens becomes
    mandatory. This measure ensures that the API remains in strict compliance
    with user privacy preferences and regulatory obligations, upholding the
    principles of transparency and user-centric data control.


    # Further info and support


    (FAQs will be added in a later version of the documentation)
  version: 0.3.0
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html
  x-camara-commonalities: 0.4.0
externalDocs:
  description: Project documentation at Camara
  url: https://github.com/camaraproject/DeviceLocation
servers:
  - url: '{apiRoot}/geofencing-subscriptions/v0.3'
    variables:
      apiRoot:
        default: http://localhost:9091
        description: API root
tags:
  - name: Geofencing subscriptions
    description: >-
      Operations to manage event subscription on geofencing events for leaving
      and entering an area
paths:
  /subscriptions:
    post:
      tags:
        - Geofencing subscriptions
      summary: Create a geofencing subscription for a device
      description: >-
        Create a subscription for a device to receive notifications when a
        device enters or exits a specified area
      operationId: createSubscription
      parameters:
        - $ref: '#/components/parameters/x-correlator'
      security:
        - openId:
            - >-
              geofencing-subscriptions:org.camaraproject.geofencing-subscriptions.v0.area-entered:create
            - >-
              geofencing-subscriptions:org.camaraproject.geofencing-subscriptions.v0.area-left:create
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubscriptionRequest'
            examples:
              CIRCLE_AREA_ENTERED:
                $ref: '#/components/examples/REQUEST_CIRCLE_AREA_ENTERED'
        required: true
      callbacks:
        notifications:
          '{$request.body#/sink}':
            post:
              summary: notifications callback
              description: >
                Important: this endpoint is to be implemented by the API
                consumer.

                The Geofencing server will call this endpoint whenever a
                Geofencing event occurs.

                `operationId` value will have to be replaced accordingly with WG
                API specific semantic
              operationId: postNotification
              parameters:
                - $ref: '#/components/parameters/x-correlator'
              requestBody:
                required: true
                content:
                  application/cloudevents+json:
                    schema:
                      $ref: '#/components/schemas/CloudEvent'
                    examples:
                      CIRCLE_AREA_ENTERED:
                        $ref: '#/components/examples/CIRCLE_AREA_ENTERED'
                      CIRCLE_AREA_LEFT:
                        $ref: '#/components/examples/CIRCLE_AREA_LEFT'
                      SUBSCRIPTION_ENDS:
                        $ref: '#/components/examples/SUBSCRIPTION_ENDS'
                      SUBSCRIPTION_UNPROCESSABLE:
                        $ref: '#/components/examples/SUBSCRIPTION_UNPROCESSABLE'
              responses:
                '204':
                  description: Successful notification
                  headers:
                    x-correlator:
                      $ref: '#/components/headers/x-correlator'
                '400':
                  $ref: '#/components/responses/Generic400'
                '401':
                  $ref: '#/components/responses/Generic401'
                '403':
                  $ref: '#/components/responses/Generic403'
                '500':
                  $ref: '#/components/responses/Generic500'
                '503':
                  $ref: '#/components/responses/Generic503'
              security:
                - {}
                - notificationsBearerAuth: []
      responses:
        '201':
          description: Created (Successful creation of subscription)
          headers:
            x-correlator:
              $ref: '#/components/headers/x-correlator'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Subscription'
        '202':
          description: >-
            Request accepted to be processed. It applies for async creation
            process.
          headers:
            x-correlator:
              $ref: '#/components/headers/x-correlator'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionAsync'
        '400':
          $ref: '#/components/responses/CreateSubscriptionBadRequest400'
        '401':
          $ref: '#/components/responses/Generic401'
        '403':
          $ref: '#/components/responses/Generic403'
        '422':
          $ref: '#/components/responses/CreateSubscriptionUnprocessableEntity422'
        '429':
          $ref: '#/components/responses/Generic429'
        '500':
          $ref: '#/components/responses/Generic500'
        '503':
          $ref: '#/components/responses/Generic503'
    get:
      tags:
        - Geofencing subscriptions
      summary: Retrieve a list of geofencing event subscription
      description: Retrieve a list of geofencing event subscription(s)
      operationId: retrieveGeofencingSubscriptionList
      parameters:
        - $ref: '#/components/parameters/x-correlator'
      security:
        - openId:
            - geofencing-subscriptions:read
      responses:
        '200':
          description: List of event subscription details
          headers:
            x-correlator:
              $ref: '#/components/headers/x-correlator'
          content:
            application/json:
              schema:
                type: array
                minItems: 0
                items:
                  $ref: '#/components/schemas/Subscription'
        '400':
          $ref: '#/components/responses/Generic400'
        '401':
          $ref: '#/components/responses/Generic401'
        '403':
          $ref: '#/components/responses/Generic403'
        '429':
          $ref: '#/components/responses/Generic429'
        '500':
          $ref: '#/components/responses/Generic500'
        '503':
          $ref: '#/components/responses/Generic503'
  /subscriptions/{subscriptionId}:
    get:
      tags:
        - Geofencing subscriptions
      summary: Operation to retrieve a subscription based on the provided ID
      description: >-
        retrieve Geofencing subscription information for a given subscription
        ID.
      operationId: retrieveGeofencingSubscription
      security:
        - openId:
            - geofencing-subscriptions:read
      parameters:
        - $ref: '#/components/parameters/SubscriptionId'
        - $ref: '#/components/parameters/x-correlator'
      responses:
        '200':
          description: OK
          headers:
            x-correlator:
              $ref: '#/components/headers/x-correlator'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Subscription'
        '400':
          $ref: '#/components/responses/SubscriptionIdRequired'
        '401':
          $ref: '#/components/responses/Generic401'
        '403':
          $ref: '#/components/responses/Generic403'
        '404':
          $ref: '#/components/responses/Generic404'
        '429':
          $ref: '#/components/responses/Generic429'
        '500':
          $ref: '#/components/responses/Generic500'
        '503':
          $ref: '#/components/responses/Generic503'
    delete:
      tags:
        - Geofencing subscriptions
      summary: Delete a Geofencing event subscription
      operationId: deleteGeofencingSubscription
      description: delete a given Geofencing subscription.
      security:
        - openId:
            - geofencing-subscriptions:delete
      parameters:
        - $ref: '#/components/parameters/SubscriptionId'
        - $ref: '#/components/parameters/x-correlator'
      responses:
        '202':
          description: >-
            Request accepted to be processed. It applies for async deletion
            process.
          headers:
            x-correlator:
              $ref: '#/components/headers/x-correlator'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubscriptionAsync'
        '204':
          description: Geofencing subscription deleted
          headers:
            x-correlator:
              $ref: '#/components/headers/x-correlator'
        '400':
          $ref: '#/components/responses/SubscriptionIdRequired'
        '401':
          $ref: '#/components/responses/Generic401'
        '403':
          $ref: '#/components/responses/Generic403'
        '404':
          $ref: '#/components/responses/Generic404'
        '429':
          $ref: '#/components/responses/Generic429'
        '500':
          $ref: '#/components/responses/Generic500'
        '503':
          $ref: '#/components/responses/Generic503'
components:
  securitySchemes:
    openId:
      description: OpenID Connect authentication
      type: openIdConnect
      openIdConnectUrl: https://example.com/.well-known/openid-configuration
  parameters:
    SubscriptionId:
      name: subscriptionId
      in: path
      description: >-
        Subscription identifier that was obtained from the create event
        subscription operation
      required: true
      schema:
        $ref: '#/components/schemas/SubscriptionId'
    x-correlator:
      name: x-correlator
      in: header
      description: Correlation id for the different services
      schema:
        type: string
  headers:
    x-correlator:
      description: Correlation id for the different services
      schema:
        type: string
  schemas:
    ErrorInfo:
      description: The error info object for possible error cases
      type: object
      required:
        - status
        - code
        - message
      properties:
        status:
          type: integer
          description: HTTP response status code
        code:
          type: string
          description: Code given to this error
        message:
          type: string
          description: Detailed error description
    SubscriptionRequest:
      description: The request for creating a event-type event subscription
      type: object
      required:
        - sink
        - protocol
        - config
        - types
      properties:
        protocol:
          $ref: '#/components/schemas/Protocol'
        sink:
          type: string
          format: url
          description: >-
            The address to which events shall be delivered using the selected
            protocol.
          example: https://endpoint.example.com/sink
        sinkCredential:
          allOf:
            - description: >-
                A sink credential provides authentication or authorization
                information necessary to enable delivery of events to a target.
            - $ref: '#/components/schemas/SinkCredential'
        types:
          description: |
            Camara Event types eligible to be delivered by this subscription.
            Note: As of now we enforce to have only event type per subscription.
          type: array
          minItems: 1
          maxItems: 1
          items:
            $ref: '#/components/schemas/SubscriptionEventType'
        config:
          $ref: '#/components/schemas/Config'
      discriminator:
        propertyName: protocol
        mapping:
          HTTP: '#/components/schemas/HTTPSubscriptionRequest'
          MQTT3: '#/components/schemas/MQTTSubscriptionRequest'
          MQTT5: '#/components/schemas/MQTTSubscriptionRequest'
          AMQP: '#/components/schemas/AMQPSubscriptionRequest'
          NATS: '#/components/schemas/NATSSubscriptionRequest'
          KAFKA: '#/components/schemas/ApacheKafkaSubscriptionRequest'
    Protocol:
      type: string
      enum:
        - HTTP
        - MQTT3
        - MQTT5
        - AMQP
        - NATS
        - KAFKA
      description: Identifier of a delivery protocol. Only HTTP is allowed for now
      example: HTTP
    Config:
      description: >
        Implementation-specific configuration parameters needed by the
        subscription manager for acquiring events.

        In CAMARA we have predefined attributes like `subscriptionExpireTime`,
        `subscriptionMaxEvents`, `initialEvent`

        Specific event type attributes must be defined in `subscriptionDetail`

        Note: if a request is performed for several event type, all subscribed
        event will use same `config` parameters.
      type: object
      required:
        - subscriptionDetail
      properties:
        subscriptionDetail:
          $ref: '#/components/schemas/SubscriptionDetail'
        subscriptionExpireTime:
          type: string
          format: date-time
          example: '2023-01-17T13:18:23.682Z'
          description: >-
            The subscription expiration time (in date-time format) requested by
            the API consumer.
        subscriptionMaxEvents:
          type: integer
          description: >-
            Identifies the maximum number of event reports to be generated (>=1)
            requested by the API consumer - Once this number is reached, the
            subscription ends.
          minimum: 1
          example: 5
        initialEvent:
          type: boolean
          description: >
            Set to `true` by API consumer if consumer wants to get an event as
            soon as the subscription is created and current situation reflects
            event request.

            Example: Consumer request area entered event. If consumer sets
            initialEvent to true and device is already in the geofence, an event
            is triggered
    SinkCredential:
      type: object
      properties:
        credentialType:
          type: string
          enum:
            - PLAIN
            - ACCESSTOKEN
            - REFRESHTOKEN
          description: The type of the credential.
      discriminator:
        propertyName: credentialType
        mapping:
          PLAIN: '#/components/schemas/PlainCredential'
          ACCESSTOKEN: '#/components/schemas/AccessTokenCredential'
          REFRESHTOKEN: '#/components/schemas/RefreshTokenCredential'
      required:
        - credentialType
    PlainCredential:
      type: object
      description: A plain credential as a combination of an identifier and a secret.
      allOf:
        - $ref: '#/components/schemas/SinkCredential'
        - type: object
          required:
            - identifier
            - secret
          properties:
            identifier:
              description: The identifier might be an account or username.
              type: string
            secret:
              description: The secret might be a password or passphrase.
              type: string
    AccessTokenCredential:
      type: object
      description: An access token credential.
      allOf:
        - $ref: '#/components/schemas/SinkCredential'
        - type: object
          properties:
            accessToken:
              description: >-
                REQUIRED. An access token is a previously acquired token
                granting access to the target resource.
              type: string
            accessTokenExpiresUtc:
              type: string
              format: date-time
              description: >-
                REQUIRED. An absolute UTC instant at which the token shall be
                considered expired.
            accessTokenType:
              description: >-
                REQUIRED. Type of the access token (See [OAuth
                2.0](https://tools.ietf.org/html/rfc6749#section-7.1)).
              type: string
              enum:
                - bearer
          required:
            - accessToken
            - accessTokenExpiresUtc
            - accessTokenType
    RefreshTokenCredential:
      type: object
      description: An access token credential with a refresh token.
      allOf:
        - $ref: '#/components/schemas/SinkCredential'
        - type: object
          properties:
            accessToken:
              description: >-
                REQUIRED. An access token is a previously acquired token
                granting access to the target resource.
              type: string
            accessTokenExpiresUtc:
              type: string
              format: date-time
              description: >-
                REQUIRED. An absolute UTC instant at which the token shall be
                considered expired.
            accessTokenType:
              description: >-
                REQUIRED. Type of the access token (See [OAuth
                2.0](https://tools.ietf.org/html/rfc6749#section-7.1)).
              type: string
              enum:
                - bearer
            refreshToken:
              description: >-
                REQUIRED. An refresh token credential used to acquire access
                tokens.
              type: string
            refreshTokenEndpoint:
              type: string
              format: uri
              description: >-
                REQUIRED. A URL at which the refresh token can be traded for an
                access token.
      required:
        - accessToken
        - accessTokenExpiresUtc
        - accessTokenType
        - refreshToken
        - refreshTokenEndpoint
    SubscriptionDetail:
      description: The detail of the requested event subscription
      type: object
      properties:
        device:
          $ref: '#/components/schemas/Device'
        area:
          $ref: '#/components/schemas/Area'
      required:
        - device
        - area
    SubscriptionEventType:
      type: string
      description: |
        area-entered - Event triggered when the device enters the given area

        area-left - Event triggered when the device leaves the given area
      enum:
        - org.camaraproject.geofencing-subscriptions.v0.area-entered
        - org.camaraproject.geofencing-subscriptions.v0.area-left
    NotificationEventType:
      type: string
      description: |
        area-entered - Event triggered when the device enters the given area

        area-left - Event triggered when the device leaves the given area

        subscription-ends - Event triggered when the subscription ends
      enum:
        - org.camaraproject.geofencing-subscriptions.v0.area-entered
        - org.camaraproject.geofencing-subscriptions.v0.area-left
        - org.camaraproject.geofencing-subscriptions.v0.subscription-ends
    Subscription:
      description: Represents a event-type subscription.
      type: object
      required:
        - sink
        - protocol
        - config
        - types
        - id
        - startsAt
      properties:
        protocol:
          $ref: '#/components/schemas/Protocol'
        sink:
          type: string
          format: url
          description: >-
            The address to which events shall be delivered using the selected
            protocol.
          example: https://endpoint.example.com/sink
        sinkCredential:
          $ref: '#/components/schemas/SinkCredential'
        types:
          description: |
            Camara Event types eligible to be delivered by this subscription.
          type: array
          items:
            type: string
        config:
          $ref: '#/components/schemas/Config'
        id:
          type: string
          description: >-
            The unique identifier of the subscription in the scope of the
            subscription manager. When this information is contained within an
            event notification, this concept SHALL be referred as
            `subscriptionId` as per [Commonalities Event Notification
            Model](https://github.com/camaraproject/Commonalities/blob/main/documentation/API-design-guidelines.md#122-event-notification).
          example: '1119920371'
        startsAt:
          type: string
          format: date-time
          description: Date when the event subscription will begin/began
        expiresAt:
          type: string
          format: date-time
          description: >-
            Date when the event subscription will expire. Only provided when
            `subscriptionExpireTime` is indicated by API client or Telco
            Operator has specific policy about that.
        status:
          type: string
          description: >-
            Current status of the subscription - Management of Subscription
            State engine is not mandatory for now. Note not all statuses may be
            considered to be implemented. Details:
              - `ACTIVATION_REQUESTED`: Subscription creation (POST) is triggered but subscription creation process is not finished yet.
              - `ACTIVE`: Subscription creation process is completed. Subscription is fully operative.
              - `INACTIVE`: Subscription is temporarily inactive, but its workflow logic is not deleted.
              - `EXPIRED`: Subscription is ended (no longer active). This status applies when subscription is ended due to `SUBSCRIPTION_EXPIRED` or `ACCESS_TOKEN_EXPIRED` event.
              - `DELETED`: Subscription is ended as deleted (no longer active). This status applies when subscription information is kept (i.e. subscription workflow is no longer active but its meta-information is kept).
          enum:
            - ACTIVATION_REQUESTED
            - ACTIVE
            - EXPIRED
            - INACTIVE
            - DELETED
      discriminator:
        propertyName: protocol
        mapping:
          HTTP: '#/components/schemas/HTTPSubscriptionResponse'
          MQTT3: '#/components/schemas/MQTTSubscriptionResponse'
          MQTT5: '#/components/schemas/MQTTSubscriptionResponse'
          AMQP: '#/components/schemas/AMQPSubscriptionResponse'
          NATS: '#/components/schemas/NATSSubscriptionResponse'
          KAFKA: '#/components/schemas/ApacheKafkaSubscriptionResponse'
    SubscriptionAsync:
      description: >-
        Response for a event-type subscription request managed asynchronously
        (Creation or Deletion)
      type: object
      properties:
        id:
          $ref: '#/components/schemas/SubscriptionId'
    SubscriptionId:
      type: string
      description: >-
        The unique identifier of the subscription in the scope of the
        subscription manager. When this information is contained within an event
        notification, this concept SHALL be referred as `subscriptionId` as per
        [Commonalities Event Notification
        Model](https://github.com/camaraproject/Commonalities/blob/main/documentation/API-design-guidelines.md#122-event-notification).
      example: qs15-h556-rt89-1298
    Device:
      description: >
        End-user equipment able to connect to a mobile network. Examples of
        devices include smartphones or IoT sensors/actuators.


        The developer can choose to provide the below specified device
        identifiers:


        * `ipv4Address`

        * `ipv6Address`

        * `phoneNumber`

        * `networkAccessIdentifier`


        NOTE1: the MNO might support only a subset of these options. The API
        invoker can provide multiple identifiers to be compatible across
        different MNOs. In this case the identifiers MUST belong to the same
        device. When returned as part of a response, the device object must
        include the same identifier values that were provided originally. Please
        note that IP addresses of devices can change and get reused, so the
        original values may no longer identify the same device. They identified
        the device at the time of the subscription request.

        NOTE2: for the Commonalities release v0.4, we are enforcing that the
        networkAccessIdentifier is only part of the schema for future-proofing,
        and CAMARA does not currently allow its use. After the CAMARA
        meta-release work is concluded and the relevant issues are resolved, its
        use will need to be explicitly documented in the guidelines.
      type: object
      properties:
        phoneNumber:
          $ref: '#/components/schemas/PhoneNumber'
        networkAccessIdentifier:
          $ref: '#/components/schemas/NetworkAccessIdentifier'
        ipv4Address:
          $ref: '#/components/schemas/DeviceIpv4Addr'
        ipv6Address:
          $ref: '#/components/schemas/DeviceIpv6Address'
      minProperties: 1
    PhoneNumber:
      description: >-
        A public identifier addressing a telephone subscription. In mobile
        networks it corresponds to the MSISDN (Mobile Station International
        Subscriber Directory Number). In order to be globally unique it has to
        be formatted in international format, according to E.164 standard,
        prefixed with '+'.
      type: string
      pattern: ^\+[1-9][0-9]{4,14}$
      example: '+123456789'
    NetworkAccessIdentifier:
      description: >-
        A public identifier addressing a subscription in a mobile network. In
        3GPP terminology, it corresponds to the GPSI formatted with the External
        Identifier ({Local Identifier}@{Domain Identifier}). Unlike the
        telephone number, the network access identifier is not subjected to
        portability ruling in force, and is individually managed by each
        operator.
      type: string
      example: 123456789@domain.com
    DeviceIpv4Addr:
      type: object
      description: >
        The device should be identified by either the public (observed) IP
        address and port as seen by the application server, or the private
        (local) and any public (observed) IP addresses in use by the device
        (this information can be obtained by various means, for example from
        some DNS servers).


        If the allocated and observed IP addresses are the same (i.e. NAT is not
        in use) then  the same address should be specified for both
        publicAddress and privateAddress.


        If NAT64 is in use, the device should be identified by its publicAddress
        and publicPort, or separately by its allocated IPv6 address (field
        ipv6Address of the Device object)


        In all cases, publicAddress must be specified, along with at least one
        of either privateAddress or publicPort, dependent upon which is known.
        In general, mobile devices cannot be identified by their public IPv4
        address alone.
      properties:
        publicAddress:
          $ref: '#/components/schemas/SingleIpv4Addr'
        privateAddress:
          $ref: '#/components/schemas/SingleIpv4Addr'
        publicPort:
          $ref: '#/components/schemas/Port'
      anyOf:
        - required:
            - publicAddress
            - privateAddress
        - required:
            - publicAddress
            - publicPort
      example:
        publicAddress: 84.125.93.10
        publicPort: 59765
    SingleIpv4Addr:
      description: A single IPv4 address with no subnet mask
      type: string
      format: ipv4
      example: 84.125.93.10
    Port:
      description: TCP or UDP port number
      type: integer
      minimum: 0
      maximum: 65535
    DeviceIpv6Address:
      description: >
        The device should be identified by the observed IPv6 address, or by any
        single IPv6 address from within the subnet allocated to the device (e.g.
        adding ::0 to the /64 prefix).
      type: string
      format: ipv6
      example: 2001:db8:85a3:8d3:1319:8a2e:370:7344
    Area:
      type: object
      properties:
        areaType:
          $ref: '#/components/schemas/AreaType'
      required:
        - areaType
      discriminator:
        propertyName: areaType
        mapping:
          CIRCLE: '#/components/schemas/Circle'
    AreaType:
      type: string
      description: |
        Type of this area.
        CIRCLE - The area is defined as a circle.
      enum:
        - CIRCLE
    Circle:
      description: Circular area
      allOf:
        - $ref: '#/components/schemas/Area'
        - type: object
          properties:
            center:
              $ref: '#/components/schemas/Point'
            radius:
              type: integer
              description: >-
                Expected accuracy for the subscription event of device location
                in m, from location (radius)
              minimum: 2000
              maximum: 200000
          required:
            - center
            - radius
      example:
        areaType: CIRCLE
        center:
          latitude: 50.735851
          longitude: 7.10066
        radius: 50000
    Point:
      type: object
      description: Coordinates (latitude, longitude) defining a location in a map
      required:
        - latitude
        - longitude
      properties:
        latitude:
          $ref: '#/components/schemas/Latitude'
        longitude:
          $ref: '#/components/schemas/Longitude'
      example:
        latitude: 50.735851
        longitude: 7.10066
    Latitude:
      description: Latitude component of a location
      type: number
      format: double
      minimum: -90
      maximum: 90
      example: 50.735851
    Longitude:
      description: Longitude component of location
      type: number
      format: double
      minimum: -180
      maximum: 180
      example: 7.10066
    CloudEvent:
      description: The notification callback
      required:
        - id
        - source
        - specversion
        - type
        - time
        - data
      properties:
        id:
          type: string
          description: identifier of this event, that must be unique in the source context.
        source:
          $ref: '#/components/schemas/Source'
        type:
          $ref: '#/components/schemas/NotificationEventType'
        specversion:
          type: string
          description: >-
            Version of the specification to which this event conforms (must be
            1.0 if it conforms to cloudevents 1.0.2 version)
          enum:
            - '1.0'
        datacontenttype:
          type: string
          description: >-
            media-type that describes the event payload encoding, must be
            "application/json" for CAMARA APIs
          enum:
            - application/json
        data:
          type: object
          description: >-
            Event details payload described in each CAMARA API and referenced by
            its type
        time:
          $ref: '#/components/schemas/DateTime'
      discriminator:
        propertyName: type
        mapping:
          org.camaraproject.geofencing-subscriptions.v0.area-left: '#/components/schemas/EventAreaLeft'
          org.camaraproject.geofencing-subscriptions.v0.area-entered: '#/components/schemas/EventAreaEntered'
          org.camaraproject.geofencing-subscriptions.v0.subscription-ends: '#/components/schemas/EventSubscriptionEnds'
    Source:
      type: string
      format: uri-reference
      minLength: 1
      description: >
        Identifies the context in which an event happened - be a non-empty
        `URI-reference` like:

        - URI with a DNS authority:
          * https://github.com/cloudevents
          * mailto:cncf-wg-serverless@lists.cncf.io
        - Universally-unique URN with a UUID:
          * urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66
        - Application-specific identifier:
          * /cloudevents/spec/pull/123
          * 1-555-123-4567
      example: https://notificationSendServer12.supertelco.com
    DateTime:
      type: string
      format: date-time
      description: Timestamp of when the occurrence happened. Must adhere to RFC 3339.
      example: '2018-04-05T17:31:00Z'
    EventAreaLeft:
      description: event structure for event when the device leaves the area
      allOf:
        - $ref: '#/components/schemas/CloudEvent'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/AreaLeft'
    EventAreaEntered:
      description: event structure for event when the device enters the area
      allOf:
        - $ref: '#/components/schemas/CloudEvent'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/AreaEntered'
    EventSubscriptionEnds:
      description: event structure for event subscription ends
      allOf:
        - $ref: '#/components/schemas/CloudEvent'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/SubscriptionEnds'
    AreaLeft:
      description: Event detail structure for area-left event
      type: object
      required:
        - device
        - area
        - subscriptionId
      properties:
        device:
          $ref: '#/components/schemas/Device'
        area:
          $ref: '#/components/schemas/Area'
        subscriptionId:
          $ref: '#/components/schemas/SubscriptionId'
    AreaEntered:
      description: Event detail structure for area-entered event
      type: object
      required:
        - device
        - area
        - subscriptionId
      properties:
        device:
          $ref: '#/components/schemas/Device'
        area:
          $ref: '#/components/schemas/Area'
        subscriptionId:
          $ref: '#/components/schemas/SubscriptionId'
    SubscriptionEnds:
      description: Event detail structure for SUBSCRIPTION_ENDS event
      type: object
      required:
        - device
        - area
        - terminationReason
        - subscriptionId
      properties:
        device:
          $ref: '#/components/schemas/Device'
        area:
          $ref: '#/components/schemas/Area'
        terminationReason:
          $ref: '#/components/schemas/TerminationReason'
        terminationDescription:
          description: Explanation why a subscription ended or had to end.
          type: string
        subscriptionId:
          $ref: '#/components/schemas/SubscriptionId'
    TerminationReason:
      type: string
      description: >
        - NETWORK_TERMINATED - API server stopped sending notification

        - SUBSCRIPTION_UNPROCESSABLE - Subscription cannot be processed due to
        some reason, e.g. because the specified area cannot be managed. Useful
        for asynchronous subscription creation.

        - SUBSCRIPTION_EXPIRED - Subscription expire time (optionally set by the
        requester) has been reached

        - SUBSCRIPTION_DELETED - Subscription was deleted by the requester

        - MAX_EVENTS_REACHED - Maximum number of events (optionally set by the
        requester) has been reached

        - ACCESS_TOKEN_EXPIRED - Access Token sinkCredential (optionally set by
        the requester) expiration time has been reached
      enum:
        - MAX_EVENTS_REACHED
        - NETWORK_TERMINATED
        - SUBSCRIPTION_UNPROCESSABLE
        - SUBSCRIPTION_EXPIRED
        - SUBSCRIPTION_DELETED
        - ACCESS_TOKEN_EXPIRED
    HTTPSubscriptionRequest:
      allOf:
        - $ref: '#/components/schemas/SubscriptionRequest'
        - type: object
          properties:
            protocolSettings:
              $ref: '#/components/schemas/HTTPSettings'
    HTTPSubscriptionResponse:
      allOf:
        - $ref: '#/components/schemas/Subscription'
        - type: object
          properties:
            protocolSettings:
              $ref: '#/components/schemas/HTTPSettings'
    HTTPSettings:
      type: object
      properties:
        headers:
          type: object
          description: >-
            A set of key/value pairs that is copied into the HTTP request as
            custom headers.


            NOTE: Use/Applicability of this concept has not been discussed in
            Commonalities under the scope of Meta Release v0.4. When required by
            an API project as an option to meet a UC/Requirement, please
            generate an issue for Commonalities discussion about it.
          additionalProperties:
            type: string
        method:
          type: string
          description: The HTTP method to use for sending the message.
          enum:
            - POST
    MQTTSubscriptionRequest:
      allOf:
        - $ref: '#/components/schemas/SubscriptionRequest'
        - type: object
          properties:
            protocolSettings:
              $ref: '#/components/schemas/MQTTSettings'
    MQTTSubscriptionResponse:
      allOf:
        - $ref: '#/components/schemas/Subscription'
        - type: object
          properties:
            protocolSettings:
              $ref: '#/components/schemas/MQTTSettings'
    MQTTSettings:
      type: object
      properties:
        topicName:
          type: string
        qos:
          type: integer
          format: int32
        retain:
          type: boolean
        expiry:
          type: integer
          format: int32
        userProperties:
          type: object
      required:
        - topicName
    AMQPSubscriptionRequest:
      allOf:
        - $ref: '#/components/schemas/SubscriptionRequest'
        - type: object
          properties:
            protocolSettings:
              $ref: '#/components/schemas/AMQPSettings'
    AMQPSubscriptionResponse:
      allOf:
        - $ref: '#/components/schemas/Subscription'
        - type: object
          properties:
            protocolSettings:
              $ref: '#/components/schemas/AMQPSettings'
    AMQPSettings:
      type: object
      properties:
        address:
          type: string
        linkName:
          type: string
        senderSettlementMode:
          type: string
          enum:
            - settled
            - unsettled
        linkProperties:
          type: object
          additionalProperties:
            type: string
    ApacheKafkaSubscriptionRequest:
      allOf:
        - $ref: '#/components/schemas/SubscriptionRequest'
        - type: object
          properties:
            protocolSettings:
              $ref: '#/components/schemas/ApacheKafkaSettings'
    ApacheKafkaSubscriptionResponse:
      allOf:
        - $ref: '#/components/schemas/Subscription'
        - type: object
          properties:
            protocolSettings:
              $ref: '#/components/schemas/ApacheKafkaSettings'
    ApacheKafkaSettings:
      type: object
      properties:
        topicName:
          type: string
        partitionKeyExtractor:
          type: string
        clientId:
          type: string
        ackMode:
          type: integer
      required:
        - topicName
    NATSSubscriptionRequest:
      allOf:
        - $ref: '#/components/schemas/SubscriptionRequest'
        - type: object
          properties:
            protocolSettings:
              $ref: '#/components/schemas/NATSSettings'
    NATSSubscriptionResponse:
      allOf:
        - $ref: '#/components/schemas/Subscription'
        - type: object
          properties:
            protocolSettings:
              $ref: '#/components/schemas/NATSSettings'
    NATSSettings:
      type: object
      properties:
        subject:
          type: string
      required:
        - subject
  responses:
    CreateSubscriptionBadRequest400:
      description: Problem with the client request
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            InvalidArgument:
              value:
                status: 400
                code: INVALID_ARGUMENT
                message: >-
                  Client specified an invalid argument, request body or query
                  param
            InvalidProtocol:
              value:
                status: 400
                code: INVALID_PROTOCOL
                message: Only HTTP is supported
            InvalidCredential:
              value:
                status: 400
                code: INVALID_CREDENTIAL
                message: Only Access token is supported
            InvalidToken:
              value:
                status: 400
                code: INVALID_TOKEN
                message: Only bearer token is supported
    Generic400:
      description: Bad Request
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          example:
            status: 400
            code: INVALID_ARGUMENT
            message: Client specified an invalid argument, request body or query param
    Generic401:
      description: Authentication problem with the client request
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          example:
            status: 401
            code: UNAUTHENTICATED
            message: >-
              Request not authenticated due to missing, invalid, or expired
              credentials.
    CreateSubscription403:
      description: Client does not have sufficient permission
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            PermissionDenied:
              value:
                status: 403
                code: PERMISSION_DENIED
                message: >-
                  Client does not have sufficient permissions to perform this
                  action
            TokenMismatch:
              value:
                status: 403
                code: SUBSCRIPTION_MISMATCH
                message: Inconsistent access token for requested events subscription
    Generic403:
      description: Forbidden
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          example:
            status: 403
            code: PERMISSION_DENIED
            message: Client does not have sufficient permissions to perform this action
    Generic404:
      description: Not found
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            GENERIC_404_NOT_FOUND:
              description: Resource is not found
              value:
                status: 404
                code: NOT_FOUND
                message: The specified resource is not found.
    CreateSubscriptionUnprocessableEntity422:
      description: Unprocessable Entity
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            PermissionDenied:
              value:
                status: 422
                code: MULTIEVENT_SUBSCRIPTION_NOT_SUPPORTED
                message: Multi event types subscription not managed
            DeviceIdentifierMismatch:
              description: >-
                Inconsistency between device identifiers not pointing to the
                same device
              value:
                status: 422
                code: DEVICE_IDENTIFIERS_MISMATCH
                message: Provided device identifiers are not consistent.
            DeviceNotApplicable:
              description: Service is not available for the provided device
              value:
                status: 422
                code: DEVICE_NOT_APPLICABLE
                message: The service is not available for the provided device.
            AreaNotCovered:
              value:
                status: 422
                code: AREA_NOT_COVERED
                message: >-
                  The specified area cannot be covered or is too small to be
                  valid
    Generic429:
      description: Too Many Requests
      headers:
        X-Correlator:
          $ref: '#/components/headers/x-correlator'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            GENERIC_429_QUOTA_EXCEEDED:
              description: Request is rejected due to exceeding a business quota limit
              value:
                status: 429
                code: QUOTA_EXCEEDED
                message: Either out of resource quota or reaching rate limiting.
            GENERIC_429_TOO_MANY_REQUESTS:
              description: API Server request limit is overpassed
              value:
                status: 429
                code: TOO_MANY_REQUESTS
                message: Either out of resource quota or reaching rate limiting.
    Generic500:
      description: Server error
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          example:
            status: 500
            code: INTERNAL
            message: Server error
    Generic503:
      description: Service unavailable. Typically the server is down.
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            GENERIC_503_UNAVAILABLE:
              description: >-
                Service is not available. Temporary situation usually related to
                maintenance process in the server side
              value:
                status: 503
                code: UNAVAILABLE
                message: Service Unavailable.
    SubscriptionIdRequired:
      description: Problem with the client request
      headers:
        x-correlator:
          $ref: '#/components/headers/x-correlator'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorInfo'
          examples:
            Generic400:
              summary: Schema validation failed
              value:
                status: 400
                code: INVALID_ARGUMENT
                message: >-
                  Client specified an invalid argument, request body or query
                  param
            subscriptionIdRequired:
              summary: subscription id is required
              value:
                status: 400
                code: INVALID_ARGUMENT
                message: 'Expected property is missing: subscriptionId'
  examples:
    REQUEST_CIRCLE_AREA_ENTERED:
      description: A sample geofence for entering for a circle area
      value:
        protocol: HTTP
        sink: https://notificationSendServer12.supertelco.com
        types:
          - org.camaraproject.geofencing-subscriptions.v0.area-entered
        config:
          subscriptionDetail:
            device:
              phoneNumber: '+12345678912'
            area:
              areaType: CIRCLE
              center:
                latitude: 50.735851
                longitude: 7.10066
              radius: 2000
          initialEvent: true
          subscriptionMaxEvents: 10
          subscriptionExpireTime: '2024-03-22T05:40:58.469Z'
    CIRCLE_AREA_ENTERED:
      description: The cloud event when a geofence area was entered
      value:
        id: '123655'
        source: https://notificationSendServer12.supertelco.com
        type: org.camaraproject.geofencing-subscriptions.v0.area-entered
        specversion: '1.0'
        datacontenttype: application/json
        time: '2023-03-22T05:40:23.682Z'
        data:
          subscriptionId: 987654321
          device:
            phoneNumber: 123456789
          area:
            areaType: CIRCLE
            center:
              latitude: 50.735851
              longitude: 7.10066
            radius: 2000
    CIRCLE_AREA_LEFT:
      description: The cloud event when a geofence area was left
      value:
        id: '123655'
        source: https://notificationSendServer12.supertelco.com
        type: org.camaraproject.geofencing-subscriptions.v0.area-left
        specversion: '1.0'
        datacontenttype: application/json
        time: '2023-03-22T05:40:23.682Z'
        data:
          subscriptionId: 987654321
          device:
            phoneNumber: 123456789
          area:
            areaType: CIRCLE
            center:
              latitude: 50.735851
              longitude: 7.10066
            radius: 2000
    SUBSCRIPTION_ENDS:
      description: The cloud event when a geofence subscription ends
      value:
        id: '123655'
        source: https://notificationSendServer12.supertelco.com
        type: org.camaraproject.geofencing-subscriptions.v0.subscription-ends
        specversion: '1.0'
        datacontenttype: application/json
        time: '2023-03-22T05:40:23.682Z'
        data:
          subscriptionId: 987654321
          device:
            phoneNumber: 123456789
          area:
            areaType: CIRCLE
            center:
              latitude: 50.735851
              longitude: 7.10066
            radius: 2000
          terminationReason: SUBSCRIPTION_EXPIRED
    SUBSCRIPTION_UNPROCESSABLE:
      description: The cloud event when the subscription process was aborted.
      value:
        id: '123655'
        source: https://notificationSendServer12.supertelco.com
        type: org.camaraproject.geofencing-subscriptions.v0.subscription-ends
        specversion: '1.0'
        datacontenttype: application/json
        time: '2023-03-22T05:40:23.682Z'
        data:
          device:
            phoneNumber: 123456789
          area:
            areaType: CIRCLE
            center:
              latitude: 50.735851
              longitude: 7.10066
            radius: 2000
          terminationReason: SUBSCRIPTION_UNPROCESSABLE
          terminationDescription: The requested area cannot be covered by the network.
